package com.klm.easymq.core.adapter.factory;

import com.klm.easymq.core.adapter.MQAdapter;
import com.klm.easymq.core.adapter.config.MQConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * MQ适配器工厂
 * 负责管理MQ适配器的创建和获取，支持SPI服务加载
 */
@Slf4j
@Component
public class MQAdapterFactory {
    
    /**
     * 适配器缓存
     */
    private final Map<String, MQAdapter> adapterCache = new ConcurrentHashMap<>();
    
    /**
     * 适配器类型映射
     */
    private final Map<String, Class<? extends MQAdapter>> adapterTypeMap = new HashMap<>();
    
    /**
     * 注入的适配器列表
     */
    @Autowired(required = false)
    private List<MQAdapter> injectedAdapters;
    
    /**
     * 初始化工厂
     */
    @PostConstruct
    public void init() {
        // 加载SPI适配器
        loadSpiAdapters();
        
        // 注册注入的适配器
        registerInjectedAdapters();
        
        log.info("MQ适配器工厂初始化完成，已加载 {} 个适配器: {}", 
                adapterTypeMap.size(), adapterTypeMap.keySet());
    }
    
    /**
     * 获取适配器
     * @param type 适配器类型
     * @return 适配器实例
     */
    public MQAdapter getAdapter(String type) {
        if (type == null || type.trim().isEmpty()) {
            throw new IllegalArgumentException("适配器类型不能为空");
        }
        
        // 先从缓存获取
        MQAdapter adapter = adapterCache.get(type);
        if (adapter != null) {
            return adapter;
        }
        
        // 创建新实例
        adapter = createAdapter(type);
        if (adapter != null) {
            adapterCache.put(type, adapter);
        }
        
        return adapter;
    }
    
    /**
     * 获取适配器（带配置）
     * @param type 适配器类型
     * @param config 配置
     * @return 适配器实例
     */
    public MQAdapter getAdapter(String type, MQConfig config) {
        MQAdapter adapter = getAdapter(type);
        if (adapter != null && config != null) {
            adapter.init(config);
        }
        return adapter;
    }
    
    /**
     * 注册适配器
     * @param type 适配器类型
     * @param adapterClass 适配器类
     */
    public void registerAdapter(String type, Class<? extends MQAdapter> adapterClass) {
        adapterTypeMap.put(type, adapterClass);
        log.info("注册MQ适配器: type={}, class={}", type, adapterClass.getName());
    }
    
    /**
     * 获取所有支持的适配器类型
     * @return 适配器类型集合
     */
    public Set<String> getSupportedTypes() {
        return new HashSet<>(adapterTypeMap.keySet());
    }
    
    /**
     * 检查是否支持指定类型
     * @param type 适配器类型
     * @return 是否支持
     */
    public boolean isSupported(String type) {
        return adapterTypeMap.containsKey(type);
    }
    
    /**
     * 创建适配器实例
     * @param type 适配器类型
     * @return 适配器实例
     */
    private MQAdapter createAdapter(String type) {
        Class<? extends MQAdapter> adapterClass = adapterTypeMap.get(type);
        if (adapterClass == null) {
            log.error("不支持的MQ适配器类型: {}", type);
            return null;
        }
        
        try {
            MQAdapter adapter = adapterClass.getDeclaredConstructor().newInstance();
            log.info("创建MQ适配器实例: type={}, class={}", type, adapterClass.getName());
            return adapter;
        } catch (Exception e) {
            log.error("创建MQ适配器实例失败: type={}, class={}", type, adapterClass.getName(), e);
            return null;
        }
    }
    
    /**
     * 加载SPI适配器
     */
    private void loadSpiAdapters() {
        try {
            ServiceLoader<MQAdapter> serviceLoader = ServiceLoader.load(MQAdapter.class);
            for (MQAdapter adapter : serviceLoader) {
                String type = adapter.getType();
                if (type != null && !type.trim().isEmpty()) {
                    adapterTypeMap.put(type, adapter.getClass());
                    log.info("通过SPI加载MQ适配器: type={}, class={}", type, adapter.getClass().getName());
                }
            }
        } catch (Exception e) {
            log.warn("加载SPI适配器失败", e);
        }
    }
    
    /**
     * 注册注入的适配器
     */
    private void registerInjectedAdapters() {
        if (injectedAdapters != null) {
            for (MQAdapter adapter : injectedAdapters) {
                String type = adapter.getType();
                if (type != null && !type.trim().isEmpty()) {
                    adapterTypeMap.put(type, adapter.getClass());
                    adapterCache.put(type, adapter);
                    log.info("注册注入的MQ适配器: type={}, class={}", type, adapter.getClass().getName());
                }
            }
        }
    }
    
    /**
     * 清理缓存
     */
    public void clearCache() {
        adapterCache.clear();
        log.info("MQ适配器缓存已清理");
    }
    
    /**
     * 关闭所有适配器
     */
    public void shutdown() {
        for (MQAdapter adapter : adapterCache.values()) {
            try {
                adapter.shutdown();
            } catch (Exception e) {
                log.error("关闭适配器失败: {}", adapter.getType(), e);
            }
        }
        adapterCache.clear();
        log.info("所有MQ适配器已关闭");
    }
} 